דף הדרכה ליצירת שרת/ לקוח עם GUI בשיעורים הקודמים למדנו כיצד ליצור שרת לקוח פשוט, ויצירת טופס המכיל פקדים כלומר יצירת GUI למשתמש, בשיעור זה נרצה להראות את הדרך לשילוב בין השניים כלומר ליצור לקוח client שיקליד את נתוני ההתחברות ( שם משתמש,,IP ) PORT בתיבות טקסט ועל ידי לחיצה על כפתור יתחבר לשרת. דוגמא למסך התחברות לשרת תזכורת : תוכנית השרת : server_socket = socket.socket() server_socket.bind(('0.0.0.0',8002)) server_socket.listen(1) print ("the server is connected") (client_socket,client_address) = server_socket.accept() client_name = client_socket.recv(1024) client_socket.send('hello '+client_name) client_socket.close() server_socket.close()
תוכנית הלקוח : my_socket = socket.socket() my_socket.connect(('192.168.43.24',8002)) my_socket.send('anat') print data my_socket.close() # '127.0.0.1' הוספת טופס: import Tkinter as tk frm_main = tk.tk() frm_main.title('client - Calc') הוספת כפתור: btn= tk.button(panel, text="connect", command=btn_send_click) ) פונקציות הכפתור : def btn_ok_click(): return lbl_name = tk.label(panel, text="user name", fg="blue", הוספת תווית : txt_name = tk.entry(panel) txt_name.insert(0, " ") txt_name.pack() הוספת תיבת טקסט:
tkinter כתובה אחרת האות הראשונה גדולה בואו נשלב בין השניים... נתחיל עם יצירת טופס והגדרת רקע שימו לב שבפייתון 2 ובפייתון 3 הסיפריה בפייתון 2 ולכן נטפל גם בזה try: # Python2 import Tkinter as tk except ImportError: # Python3 import tkinter as tk frm_main = tk.tk() frm_main.title('client - Calc') image = tk.photoimage(file="c:\elza1.gif") # get the width and height of the image w = image.width() h = image.height() # position coordinates of frm_main 'upper left corner' x = 200 y = 50 # size the frm_main to fit the image frm_main.geometry("%dx%d+%d+%d" % (w, h, x, y)) # tk.frame has no image argument # so use a label as a panel/frame panel = tk.label(frm_main, image=image) panel.pack(side='top', fill='both', expand='yes') הגדרת הטופס הוספת רקע הגדרנו panel שהוא בעצם תווית שישמש אותנו לשים את תמונת הרקע על הטופס
הוספת תוויות ותיבות טקסט לתוכםם נקלוט את שם המשתמש, IP PORT, lbl_name = tk.label(panel, text="user name", fg="blue", txt_name = tk.entry(panel) txt_name.insert(0, " ") txt_name.pack() lbl_ip = tk.label(panel, text="server ip", fg="blue", txt_srv_ip = tk.entry(panel) txt_srv_ip.insert(0, " ") txt_srv_ip.pack() lbl_port = tk.label(panel, text="server port", fg="blue", txt_srv_port = tk.entry(panel) txt_srv_port.insert(0, " ") txt_srv_port.pack() הוספת כפתור התחבר connect btn_ok = tk.button(panel, text="connect", width=10, command=btn_ok_click) # Add a button to the window... btn_ok.pack() my_socket = socket.socket() הפונקציה שהכפתור יבצע היא : def btn_ok_click(): port=int(txt_srv_port.get()) ip=txt_srv_ip.get() user_name=txt_name.get() data = user_name + "," + ip + ", " + str(port) txt_info.insert(0, data) my_socket.connect((ip,port)) # or your friend IP like '192.168.43.24' my_socket.send(user_name) lbl_tmp = tk.label(panel,text=data).pack() #my_socket.close() return הסבר : בפונקציה זו הוגדרו 3 משתנים : int והומר ל txt_srv_port המקבל את הערך שהוקלד בתיבת הטקסט port txt_srv_ip המקבל את הערך שהוקלד בתיבת הטקסט - Ip txt_name המקבל את הערך שהוקלד בתיבת הטקסט - user_name לאחר שיש לנו את נתוני ההתחברות הבסיסיים נשתמש בחיבור שנלמד בצד לקוח על מנת להתחבר לשרת
נרצה לשפר את התרגיל באופן הבא : לאחר ההתחברות הראשונית של הלקוח לשרת, הלקוח ישלח לשרת פעולה חשבונית כלשהי ועל השרת להחזיר תשובה לדוגמא : הלקוח שולח : 2 3 + השרת יחזיר תשובה 5 נוסף ללקוח תיבת טקסט שבתוכנה יכול להקליד את הפעולה החשבונית וכפתור שליחה txt_mess = tk.entry(panel) txt_mess.insert(0, " ") txt_mess.pack() btn_send = tk.button(panel, text="send", width=10, command=btn_send_click) # Add a button to the window... btn_send.pack() def btn_send_click(): הפונקציה של הכפתור תיהיה my_socket.send(txt_mess.get()) lbl_tmp = tk.label(panel,text=data).pack()
כמובן שהשרת ישתנה בהתאם ועכשיו הוא נראה כך : server_socket = socket.socket() server_socket.bind(('0.0.0.0',8004)) חלק זה מטפל בהתחברות הראשונית של הלקוח server_socket.listen(1) print ("the server is connected") (client_socket,client_address) = server_socket.accept() client_name = client_socket.recv(1024) print client_name+" connected" client_socket.send('hello '+client_name) חלק זה מטפל בקבלת הפעולה החשבונית ניתוח ושליחת תשובה ללקוח while True: client_str = client_socket.recv(1024) client_str = str(client_str).replace(" ",":") tmpstr=str(client_str).split(":") if tmpstr[1]=="+": client_socket.send(str(int(tmpstr[0])+int(tmpstr[2]))) elif tmpstr[1]=="-": client_socket.send(str(int(tmpstr[0])-int(tmpstr[2]))) elif tmpstr[1]=="*": client_socket.send(str(int(tmpstr[0])*int(tmpstr[2]))) elif tmpstr[1]=="/": client_socket.send(str(int(tmpstr[0])/int(tmpstr[2]))) # client_socket.send(client_name) client_socket.close() server_socket.close()
נסתכל על התוכנית במלואה : צד לקוח : try: # Python2 import Tkinter as tk except ImportError: # Python3 import tkinter as tk my_socket = socket.socket() def btn_ok_click(): port=8004#int(txt_srv_port.get()) ip="192.168.1.2"#txt_srv_ip.get() user_name="anat"#txt_name.get() data = user_name + "," + ip + ", " + str(port) txt_info.insert(0, data) my_socket.connect((ip,port)) # or your friend IP like '192.168.43.24' my_socket.send(user_name) lbl_tmp = tk.label(panel,text=data).pack() #my_socket.close() return def btn_send_click(): my_socket.send(txt_mess.get()) lbl_tmp = tk.label(panel,text=data).pack() """ init_form """ frm_main = tk.tk() frm_main.title('client - Calc') image = tk.photoimage(file="c:\elza1.gif") # get the width and height of the image w = image.width() h = image.height() # position coordinates of frm_main 'upper left corner' x = 200 y = 50 # size the frm_main to fit the image frm_main.geometry("%dx%d+%d+%d" % (w, h, x, y)) # tk.frame has no image argument # so use a label as a panel/frame panel = tk.label(frm_main, image=image) panel.pack(side='top', fill='both', expand='yes') """ put labels and button on form """ #button = tk.button(panel, text='button widget') #button.pack(side='top', pady=5) lbl_name = tk.label(panel, text="user name", fg="blue",
txt_name = tk.entry(panel) txt_name.insert(0, " ") txt_name.pack() lbl_ip = tk.label(panel, text="server ip", fg="blue", txt_srv_ip = tk.entry(panel) txt_srv_ip.insert(0, " ") txt_srv_ip.pack() lbl_port = tk.label(panel, text="server port", fg="blue", txt_srv_port = tk.entry(panel) txt_srv_port.insert(0, " ") txt_srv_port.pack() btn_ok = tk.button(panel, text="connect", width=10, command=btn_ok_click) # Add a button to the window... btn_ok.pack() txt_info = tk.entry(panel) txt_info.insert(0, " ") txt_info.pack() txt_mess = tk.entry(panel) txt_mess.insert(0, " ") txt_mess.pack() btn_send = tk.button(panel, text="send", width=10, command=btn_send_click) # Add a button to the window... btn_send.pack() panel.image = image frm_main.mainloop() #my_socket.close()